#include "ec20.h"
#include "include.h"

char array_RDY[RDY_Str_Len] = "\r\nRDY\r\n";

char array_OK[OK_Str_Len] = "\r\nOK\r\n";

char array_QICLOSE[QICLOSE_Str_Len] = "AT+QICLOSE=0\r\n";

char array_CONNECT[CONNECT_Str_Len] = "\r\nCONNECT\r\n";        //连接

char array_QISEND[QISEND_Str_Len] = "AT+QISEND=0\r\n";  //

//char ec20_connect_sendbuf[56] = "AT+QIOPEN=1,0,\"TCP\",\"123.138.72.106\",8890,0,2\r\n";                // 连接服务器
char ec20_connect_sendbuf[56] = "";                // 连接服务器
char array_CSQ[CSQ_Str_Len] = "AT+CSQ\r\n";  // 查询信号强度

void EC20_recv_package_callback( uint8_t *data, uint16_t size )
{
  memcpy( rk.ec20.buf, data, size );
  rk.ec20.len = size;
  rk.flag.recv_EC20 = true;
}

void set_device_addr( ADDR *addr )
{
  rk.hyper_parameter.addr = *addr;
  initflag_set( Extflash_Init_Flag );
  HAL_Delay(20);
  hyper_parameter_set();
  HAL_Delay(20);
  parameter_set();
  HAL_Delay(20);

  if( rk.parameter.control_object == Remote_Control_Mode )
  {
    rk.upload.confirm_type  = AFN_Set_Device_Addr;
  }
}
void set_device_addr_by_uart( uint8_t value )
{
  if( value == 0x0A)
  {
    initflag_set( Extflash_Init_Flag );
    HAL_Delay(20);
    memcpy( &rk.hyper_parameter.addr, recv_uart_array_addr, 10 );
    hyper_parameter_set();
    HAL_Delay(20);
    parameter_set();
    HAL_Delay(20);
    rk.flag.system_restart = true;
    HAL_Delay(100);
    uart_log("device revc : uart set valid addr!\r\n");
    HAL_Delay(100);
  }
  else if( value == 0x0B )
  {
    send_set_addr_fail_to_uart();
    HAL_Delay(100);
    uart_log("device revc : uart set invalid addr!\r\n");
    HAL_Delay(100);
  }
}
void set_device_restart( void )
{
  rk.flag.system_restart = true;
  if( rk.parameter.control_object == Remote_Control_Mode )
  {
    rk.upload.confirm_type = AFN_Set_Device_Restart;
  }
}

void set_hyper_parameter( uint8_t *data )
{
  memcpy( &rk.hyper_parameter, data, Hyp_Pam_Len );
  rk.hyper_parameter.angle_to_displacement_coefficient = (float)rk.hyper_parameter.gate_height / ((float)rk.hyper_parameter.encoder_upper_limit - (float)rk.hyper_parameter.encoder_lower_limit);

  initflag_set( Extflash_Init_Flag );
  HAL_Delay(20);
  hyper_parameter_set();
  HAL_Delay(20);
  parameter_set();
  HAL_Delay(20);
  if( rk.parameter.control_object == Remote_Control_Mode )
  {
    rk.upload.confirm_type  = AFN_Set_Hyper_Parameter;
  }
}
void reset_hyper_parameter( void )
{

  initflag_set( 0xFF );
  rk.flag.system_restart = true;
  if( rk.parameter.control_object == Remote_Control_Mode )
  {
    rk.upload.confirm_type = AFN_Reset_Hyper_Parameter;
  }
}

void EC20_data_handle( void )
{
  int i = 0;
  uint32_t temp = 0;
  uint8_t  CS_checknum = 0;
  uint16_t datelen;
  uint8_t  array_addr[Addr_Len];
  uint8_t  array_cycle[Cycle_Len];
  uint8_t  array_clock[Clock_Len];
  uint8_t  array_server_ip_port[Server_Ip_Port_Len];
  uint8_t  array_hyp_pam[Hyp_Pam_Len];
  char str[128];
  if( rk.ec20.buf[0] != 0x68 || rk.ec20.buf[rk.ec20.len-1] != 0x16 )
  {
    return ;
  }
  if( BOOTLOADER && (process == Recv_New_APP_To_APP2) )
  {
    datelen = (((uint16_t)rk.ec20.buf[Package_Control_Data_Pos] << 4) & 0x700) | rk.ec20.buf[Package_Len_Pos];
  }
  else
  {
    datelen = rk.ec20.buf[Package_Len_Pos];
  }

  //cs check
  for( i = Package_Control_Data_Pos; i < Package_Control_Data_Pos + datelen; i++ )
  {
    CS_checknum += rk.ec20.buf[i];
  }

  if( rk.ec20.buf[rk.ec20.len - 2] != CS_checknum )
  {
    return ;
  }

  if( rk.ec20.buf[Package_User_Data_Region_Size] == AFN_Login )
  {
    rk.flag.device_login_success = true;
  }

  if( rk.flag.device_login_success == false )
  {
    return ;
  }
  rk.timer.EC20_stop_work_timer = 0;
//  datelen = (((uint16_t)rk.ec20.buf[Package_Control_Data_Pos] << 4) & 0x700) | rk.ec20.buf[Package_Len_Pos];
  rk.upload.confirm_type = 0;
  switch( rk.ec20.buf[Package_User_Data_Region_Size] )
  {
    case AFN_Login:                                     //收到注册成功
      rk.flag.device_login_success = true;
      uart_log("device revc : device login!\r\n");
      break;
    case AFN_Get_Whether_Valid_Addr:                    // 询问是否为有效地址
      set_device_addr_by_uart( rk.ec20.buf[Package_Data_Region_Size] );
      break;
//      uart_log("device revc : uart\r\n");
    case AFN_Heart:
    case AFN_Fanction_Data:                             // 收到工况或者是业务数据确认包
    case AFN_THA_Data:
      rk.flag.recv_fanction_THA_heart_data_confirm = true;
      break;

    case AFN_Call_Fanction_Data:                        //召测业务数据
      rk.upload.AFN_call_type = AFN_Call_Fanction_Data;
      upload_package = upload_function_data_package;
      upload_package_init();
      upload_package_crc_end( upload_package() );
      uart_log("device revc : call function data!\r\n");
      break;

    case AFN_Call_THA_Data:                             //召测工况数据
      rk.upload.AFN_call_type = AFN_Call_THA_Data;
      upload_package = upload_THA_data_package;
      upload_package_init();
      upload_package_crc_end( upload_package() );
      uart_log("device revc : call THA data!\r\n");
      break;

    case AFN_History_Call_Fanction_Data:                //召测历史业务数据
      rk.upload.AFN_call_type = AFN_History_Call_Fanction_Data;
      upload_package = upload_function_data_package;
      upload_package_init();
      upload_package_crc_end( upload_package() );
      uart_log("device revc : call history fanction data!\r\n");
      break;

    case AFN_Hyper_Parameter:                           // 召测超参数
      rk.upload.AFN_call_type = AFN_Hyper_Parameter;
      upload_package = upload_hyper_parameter_package;
      upload_package_init();
      upload_package_crc_end( upload_package() );
      break;

    case AFN_Set_Device_Addr:                           //设置遥测终端地址
      memcpy( array_addr, rk.ec20.buf+Package_Data_Region_Size, Addr_Len );
      set_device_addr( (ADDR *)array_addr );
      uart_log("device revc : set device addr!\r\n");
      break;

    case AFN_Set_Device_Clock:                          //设置遥测终端时钟

      memcpy( array_clock, rk.ec20.buf+Package_Data_Region_Size, Clock_Len );
      set_device_clock( array_clock );
      uart_log("device revc : set device clock!\r\n");
      break;

    case AFN_Set_Device_Mode:                           //设置遥测终端模式（远程。现地）
      set_device_mode( rk.ec20.buf[Package_Data_Region_Size] );
      uart_log("device revc : set device mode!\r\n");
      break;

    case AFN_Set_Device_Upload_Cycle:                   //设置遥测终端上报周期
      memcpy( array_cycle, rk.ec20.buf+Package_Data_Region_Size, Cycle_Len );
      set_device_upload_cycle( array_cycle );
      uart_log("device revc : set device upload cycle!\r\n");
      break;

    case AFN_Set_Device_Upload_Target:                  //设置遥测终端上报中心（目标）
      memcpy( array_server_ip_port, rk.ec20.buf+Package_Data_Region_Size, Server_Ip_Port_Len );
      set_device_upload_target( array_server_ip_port );
      uart_log("device revc : set device upload target!\r\n");
      break;

    case AFN_Set_Device_Restart:                        //设置遥测终端重启
      set_device_restart();
      uart_log("device revc : set device restart!\r\n");
      break;

    case AFN_Set_Hyper_Parameter:                       // 设置超参数
      memcpy( array_hyp_pam, rk.ec20.buf+Package_Data_Region_Size, Hyp_Pam_Len );
      set_hyper_parameter( array_hyp_pam );
      uart_log("device revc : set device hyper parameter!\r\n");
      break;

    case AFN_Reset_Hyper_Parameter:                     // 超参数恢复出场设置
      reset_hyper_parameter();
      uart_log("device revc : reset device hyper parameter!\r\n");
      break;

    case AFN_Set_Remote_Control_Mode:                   //设置遥测终端控制模式（自动，手动）
      if( rk.parameter.control_object != Remote_Control_Mode )
      {
        break;
      }
      set_control_mode( rk.ec20.buf[Package_Data_Region_Size] );
      uart_log("device revc : set device control mode!\r\n");
      break;

    case AFN_Set_Gate_Status:                           //手动模式下设置闸门状态

       rk.parameter.control_mode = Manual_Control_Mode;
      if( rk.ec20.buf[Package_Data_Region_Size] == STOP )
      {
        set_gate_status( rk.ec20.buf[Package_Data_Region_Size] );
        sprintf(str, "device revc : set gate stop!, encoder value : %d current : %f\r\n", rk.encoder.turn_nums, rk.ina226.current );
        uart_log( str );
        break;
      }
      else
      {
        rk.flag.gate_control_change = true;
      }
      if( rk.parameter.control_object != Remote_Control_Mode  )
      {
        break;
      }
      set_gate_status( rk.ec20.buf[Package_Data_Region_Size] );
      uart_log("device revc : set gate status!\r\n");
      break;

    case AFN_Set_Gate_Auto_Option:                      //自动模式下设置自动参数
      rk.parameter.control_mode = Auto_Control_Mode;
      if( rk.parameter.control_object != Remote_Control_Mode )
      {
        break;
      }
      temp =  (rk.ec20.buf[Package_Data_Region_Size+1] << 24)
            | (rk.ec20.buf[Package_Data_Region_Size+2] << 16)
            | (rk.ec20.buf[Package_Data_Region_Size+3] << 8)
            |  rk.ec20.buf[Package_Data_Region_Size+4];

      set_gate_auto_option( rk.ec20.buf[Package_Data_Region_Size], temp );
      uart_log("device revc : set gate auto!\r\n");
      break;

    case AFN_IAP_Update_Work:                           // 远程升级
      if( !BOOTLOADER )
      {
        break;
      }
      uint8_t str[56];
      recv_bin_handle( rk.ec20.buf+Package_Data_Region_Size, 1034 );

      return ;
      break;

    case AFN_IAP_Update_Start:                          // 进入bootloader
      if( BOOTLOADER )
      {
        break;
      }
      start_bootloader_recv_bin( rk.ec20.buf+Package_Data_Region_Size );
      uart_log("device revc : start iap update!\r\n");
      break;

    case AFN_Reset_App_Bin:
      if( BOOTLOADER )
      {
        break;
      }
      set_bootloader_copy_app3_to_app1();
      uart_log("device revc : reset app bin!\r\n");
      break;
    case AFN_Study:
      calibration_system_parameter();
      rk.upload.confirm_type = AFN_Study;
      break;
    default:

      break;


  }

  //发送确认包
  if( (rk.upload.confirm_type != AFN_Login) && ( (rk.upload.confirm_type & 0xF0) != 0x60) &&  ((rk.upload.confirm_type & 0xF0) != 0x90) )
  {
    rk.upload.txbuf[Package_User_Data_Region_Size]  = 0x0A;       //执行结果

    if( rk.upload.confirm_type == AFN_Set_Device_Clock )
    {
      // check RTC
      check_clock_sync( array_clock );
    }
    upload_package = upload_confirm_package;
    upload_package_init();
    upload_package_crc_end( upload_package() );
    if( rk.upload.confirm_type == AFN_Set_Device_Clock )
    {
      //
      EC20_send_data( rk.upload.txbuf, rk.upload.txbuf[Package_Len_Pos]+Package_Aside_From_User_Data );
    }

  }
}


unsigned char 	uart1txbuf[UART_TX_BUFF_SIZE];
void uart1_send(unsigned char *buff, unsigned short len, unsigned char dmaflag)
{
  if(dmaflag == 1)
  {

    memset(uart1txbuf, 0, UART_TX_BUFF_SIZE);
    memcpy(uart1txbuf, buff, len);

    __HAL_UART_ENABLE_IT(&huart1,  UART_IT_TC);//TC interrupt
    HAL_UART_Transmit_DMA(&huart1, uart1txbuf, len);
  }
  else
  {
    HAL_UART_Transmit(&huart1, buff, len, 0xFF);

  }
}

void EC20_send_str( char *str )
{
  uart1_send((unsigned char *)str, strlen(str), okey );
}


uint8_t find_connect( char *buf, uint16_t len, uint8_t *pos )
{
  uint8_t array_cut[CONNECT_Str_Len];
  uint8_t ret = 0x01;
  char str_r = '\r';
  int i;
  for( i = 0; i < len; i++ )
  {
    if( buf[i] == str_r )
    {
      *pos = i;
      memcpy( array_cut, buf + *pos, CONNECT_Str_Len );
      ret = memcmp( array_cut, array_CONNECT, CONNECT_Str_Len);
      if( ret == 0 )
      {
        break;
      }
    }
  }
  return ret;
}
uint8_t find_ok( char *buf, uint16_t len, uint8_t *pos )
{

  uint8_t array_cut[OK_Str_Len];
  uint8_t ret = 0x01;
  char str_r = '\r';
  int i;
  for( i = 0; i < len; i++ )
  {
    if( buf[i] == str_r )
    {
      *pos = i;
      memcpy( array_cut, buf + *pos, OK_Str_Len );
      ret = memcmp( array_cut, array_OK, OK_Str_Len);
      if( ret == 0 )
      {
        break;
      }
    }
  }
  return ret;
}
uint8_t tx1_buf[256];
void EC20_send_data( uint8_t *data, uint16_t size )
{
  memcpy( tx1_buf, data, size );
  HAL_UART_Transmit_DMA( &huart1, tx1_buf, size );

}

void recv_EC20_signal_handle( void )
{
  uint8_t ret;
  uint8_t pos;
  if( rk.flag.EC20_connect_success == true )
  {
    //  get signal
    if( rk.ec20.get_signal_step == 0 )
    {
      ret = memcmp( rk.ec20.buf, array_OK, OK_Str_Len );
      if( ret == 0 )
      {
        rk.ec20.get_signal_step++;
        memset(rk.ec20.buf, 0, 256 );
        return ;
      }
    }
    else if( rk.ec20.get_signal_step == 1 )
    {
      if( rk.flag.EC20_signal_get == false )
      {
        //start
        ret = find_ok( (char *)rk.ec20.buf, rk.ec20.len, &pos );
        if(pos == 0)
        {
          memset(rk.ec20.buf, 0, 256 );
          return ;
        }
        if( ret == 0 )
        {
          rk.ec20.get_signal_step++;
          rk.ec20.signal_strength_value = get_ec20_signal_value( (char *)rk.ec20.buf, pos );
          rk.flag.EC20_signal_get = true;
          memset(rk.ec20.buf, 0, 256 );
          return ;
        }
      }
    }
    else if( rk.ec20.get_signal_step == 2 )
    {
      ret = find_connect( (char *)rk.ec20.buf, rk.ec20.len, &pos );
      if( ret == 0 )
      {
        rk.ec20.get_signal_step++;
        memset(rk.ec20.buf, 0, 256 );
        return ;
      }
    }
  }
}
void get_ec20_signal_strength( void )
{
  rk.ec20.get_signal_step = 0;
  rk.timer.EC20_get_signal_timer = 0;
  rk.timer.EC20_init_timer = 0;
  while( rk.timer.EC20_init_timer < 5 * A_Second )
  {
    if( rk.flag.recv_EC20 == true )
    {
      recv_EC20_package_handle();
    }
    if( rk.timer.EC20_get_signal_timer >= Get_Ec20_Signal_Strength_Timer_Step )
    {
      GPIO_MCU_WDI_Toggle;
      if( rk.ec20.get_signal_step == 0 )
      {
        EC20_send_str( "+++" );
      }
      else if( rk.ec20.get_signal_step == 1 )
      {
        EC20_send_str( array_CSQ );
      }
      else if( rk.ec20.get_signal_step == 2 )
      {
        EC20_send_str( "ATO\r\n" );
      }
      if( rk.flag.EC20_signal_get == true )
      {
        char str[56];
        sprintf(str, "EC20 get singal success! value:%d\r\n", rk.ec20.signal_strength_value );
        uart_log( str );
        break;
      }
      rk.timer.EC20_get_signal_timer = 0;
    }
  }
  if( rk.timer.EC20_init_timer >= 5 * A_Second )
  {
    uart_log("EC20 get singal failure!\r\n");
  }
}
unsigned char get_ec20_signal_value( char *buf, uint16_t pos )
{
  unsigned char value = 0;

  if( buf[pos-7] == ' ' )
  {
    value = buf[pos-6] -  '0' ;
  }
  else
  {
    value = (buf[pos-7] - '0') * 10+ (buf[pos-6] - '0');
  }
  return value;
}

void recv_EC20_package_handle( void )
{
  uint8_t ret;
  uint8_t pos;
  if( rk.flag.EC20_start == false )
  {
    //start
    ret = memcmp( rk.ec20.buf, array_RDY, RDY_Str_Len );
    if( ret == 0 )
    {
      rk.flag.EC20_start = true;
      memset(rk.ec20.buf, 0, 256 );
      return ;
    }
  }

  recv_EC20_signal_handle();


  if( rk.flag.EC20_connect_success == false )
  {
    ret = find_connect( (char *)rk.ec20.buf, rk.ec20.len, &pos );
    if( ret == 0 )
    {
       rk.flag.EC20_connect_success = true;

    }
  }

  else
  {
    EC20_data_handle();
  }
  //flag
  memset(rk.ec20.buf, 0, 256 );
  rk.flag.recv_EC20 = false;
}

void ec20_connect_data_package( uint8_t *ip, uint16_t port, uint8_t mode, char *out_str )
{
  char   str[56] = "";
  sprintf( str, "AT+QIOPEN=1,0,\"TCP\",\"%u.%u.%u.%u\",%u,0,%u\r\n", ip[0], ip[1], ip[2], ip[3], port, mode );
//                "AT+QIOPEN=1,0,\"TCP\",\"123.138.72.106\",8890,0,2\r\n"
  memcpy(out_str, str, sizeof(str) );
}

void EC20_connection_establishment( void )
{
  rk.timer.EC20_init_timer = 0;
  rk.timer.EC20_signal_timer = 0;
  rk.timer.EC20_trigger_timer = 0;
  while( rk.timer.EC20_trigger_timer < EC20_Trigger_Timer_Max ){}
  GPIO_P3V8_EN_RESET;
  uart_log("EC20 trigger success!\r\n");
  GPIO_MCU_WDI_Toggle;
  rk.flag.EC20_trigger    = true;

  while( rk.timer.EC20_init_timer < EC20_Init_Max )
  {
    HAL_Delay(200);
    GPIO_MCU_WDI_Toggle;

    if( rk.flag.recv_EC20 == true )
    {
      recv_EC20_package_handle();
    }

    if( rk.flag.EC20_start )
    {
      if( rk.timer.EC20_connect_timer >= EC20_Connect_Timer_Interval )
      {
        GPIO_MCU_WDI_Toggle;
        ec20_connect_data_package( rk.hyper_parameter.upload_target_server_ip, rk.hyper_parameter.upload_target_port, EC20_SeriaNet, ec20_connect_sendbuf );
        EC20_send_str( ec20_connect_sendbuf );
        rk.timer.EC20_connect_timer = 0;
      }

      if( rk.flag.EC20_connect_success == true )
      {
        uart_log("EC20 connect success!\r\n");
        break;
      }
    }
  }
  if( rk.timer.EC20_init_timer >= EC20_Init_Max )
  {
    memset( &rk.timer, 0, sizeof(rk.timer) );
    uart_log("EC20 connect failure!\r\n");
  }

}
